package com.chenbei.common.config;

import com.chenbei.common.handler.serializer.LongToStringSerializer;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.List;
import java.util.stream.Collectors;

@Configuration
@Slf4j
public class JacksonConfig {

    @Bean
    public ObjectMapper objectMapper(ObjectProvider<AnnotationIntrospector> introspectorProvider) {
        ObjectMapper mapper = new ObjectMapper();

        // 注册 Java 8 时间模块，否则无法正确处理 LocalDateTime
        mapper.registerModule(new JavaTimeModule());
        // 禁用日期时间转时间戳，必须禁用，否则日期会变成时间戳格式
        mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);

        // 忽略 JSON 中存在的但 Java 类没有的字段
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

        // 获取所有自定义introspectors
        List<AnnotationIntrospector> annotationIntrospectors = introspectorProvider.orderedStream().collect(Collectors.toList());

        //合并所有自定义的Introspectors
        AnnotationIntrospector combinedIntrospector = combineIntrospectors(annotationIntrospectors);

        AnnotationIntrospector finalIntrospector = AnnotationIntrospector.pair(
                combinedIntrospector,
                mapper.getSerializationConfig().getAnnotationIntrospector()
                );

        mapper.setAnnotationIntrospector(finalIntrospector);

        SimpleModule simpleModule = new SimpleModule();
        simpleModule.addSerializer(Long.class,  new LongToStringSerializer());
        simpleModule.addSerializer(long.class, new LongToStringSerializer());
        mapper.registerModule(simpleModule);

        return mapper;
    }

    private AnnotationIntrospector combineIntrospectors(List<AnnotationIntrospector> introspectors) {
        if (introspectors == null || introspectors.isEmpty()) {
            return AnnotationIntrospector.nopInstance();
        }
        AnnotationIntrospector result = introspectors.get(0);
        for (int i = 1; i < introspectors.size(); i++) {
            result = AnnotationIntrospector.pair(result, introspectors.get(i));
        }
        return result;
    }

    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
        //long转成string，避免前端精度丢失
        return builder -> builder.serializerByType(Long.class, ToStringSerializer.instance)
                .serializerByType(Long.TYPE, ToStringSerializer.instance);
    }
}
